#include "travellabel.h"
#include <QDebug>

// 构造函数：初始化 TravelLabel 实例
TravelLabel::TravelLabel(QWidget *parent)
    : QLabel(parent), scaleFactor(1.0), currentLineIndex(0) // 初始化缩放因子为 1.0，当前线段索引为 0
{
    lineAnimationTimer = new QTimer(this); // 创建定时器对象
    connect(lineAnimationTimer, &QTimer::timeout, this, &TravelLabel::updateLineAnimation); // 连接定时器的超时信号到更新动画槽
}

// 设置位置映射
void TravelLabel::setPositionsMap(const QMap<QString, QPointF> &positionsMap)
{
    this->positionsMap = positionsMap; // 更新位置映射
    updateAdjustedPositions(); // 更新调整后的点位置
    update(); // 触发重绘
}

// 设置中心位置
void TravelLabel::setCentralPosition(const QPointF &centralPosition)
{
    this->centralPosition = centralPosition; // 更新中心位置
    updateAdjustedPositions(); // 更新调整后的点位置
    update(); // 触发重绘
}

// 设置缩放因子
void TravelLabel::setScaleFactor(double factor)
{
    this->scaleFactor = factor; // 更新缩放因子
    updateAdjustedPositions(); // 更新调整后的点位置
    update(); // 触发重绘
}

// 设置点名称顺序
void TravelLabel::setOrderedNames(const QStringList &names)
{
    this->orderedNames = names; // 更新点名称顺序
    updateAdjustedPositions(); // 更新调整后的点位置
    update(); // 触发重绘
}

// 设置点的颜色
void TravelLabel::setPointColor(QVector<QColor> pointColor){
    this->pointColor = pointColor; // 更新点颜色
    update(); // 触发重绘
}

// 设置连接序列
void TravelLabel::setConnectionSequence(const QVector<int> &sequence)
{
    this->connectionSequence = sequence; // 更新连接序列
    currentLineIndex = 0; // 重置当前线段索引
    if (drawLines && !connectionSequence.isEmpty()) {
        lineAnimationTimer->start(200); // 如果绘制线段且连接序列不为空，则启动动画定时器
    }
    update(); // 触发重绘
}

// 设置是否绘制点
void TravelLabel::setDrawPoints(bool enable)
{
    this->drawPoints = enable; // 更新是否绘制点的标志
    update(); // 触发重绘
}

// 设置是否绘制线段
void TravelLabel::setDrawLines(bool enable)
{
    this->drawLines = enable; // 更新是否绘制线段的标志
    if (enable && !connectionSequence.isEmpty()) {
        currentLineIndex = 0; // 重置当前线段索引
        lineAnimationTimer->start(200); // 启动动画定时器
    } else {
        lineAnimationTimer->stop(); // 停止动画定时器
    }
    update(); // 触发重绘
}

// 更新调整后的点位置
void TravelLabel::updateAdjustedPositions()
{
    adjustedPositionsList.clear(); // 清空调整后的点位置列表

    if (positionsMap.isEmpty() || orderedNames.isEmpty()) {
        return; // 如果位置映射或点名称顺序为空，直接返回
    }

    double centerX = width() / 2.0; // 计算控件的中心 X 坐标
    double centerY = height() / 2.0 + 35; // 计算控件的中心 Y 坐标（加上偏移量）

    // 按照 orderedNames 的顺序调整点的位置
    for (const QString &name : orderedNames) {
        if (positionsMap.contains(name)) {
            QPointF pos = positionsMap[name]; // 获取点的位置

            // 计算相对于中心点的坐标差并乘以缩放因子
            QPointF relativePos = (pos - centralPosition) * scaleFactor;
            QPointF adjustedPos = QPointF(centerX + relativePos.x(), centerY - relativePos.y() * 1.3);

            // 将调整后的点添加到 QVector 中
            adjustedPositionsList.append(adjustedPos);
        }
    }
}

// 绘制事件处理函数
void TravelLabel::paintEvent(QPaintEvent *event)
{
    QLabel::paintEvent(event); // 调用 QLabel 的绘制行为

    if (adjustedPositionsList.isEmpty()) {
        return; // 如果没有调整后的点位置数据，直接返回
    }

    QPainter painter(this); // 创建绘图工具

    // 绘制点
    if (drawPoints) {
        if (pointColor.size() + 30 < adjustedPositionsList.size()) {
            painter.setPen(Qt::red); // 设置画笔颜色为红色
            painter.setBrush(Qt::red); // 设置画刷颜色为红色
            int i = 0;
            for (const auto &adjustedPos : adjustedPositionsList) {
                // 绘制点（当索引大于等于 30 时）
                if (i >= 30) {
                    painter.drawEllipse(adjustedPos, 5, 5); // 绘制半径为 5 的圆形点
                }
                i++;
            }
        } else {
            int i = 0;
            for (const auto &adjustedPos : adjustedPositionsList) {
                // 绘制点（当索引大于等于 30 时）
                if (i >= 30) {
                    painter.setPen(pointColor[i - 30]); // 设置画笔颜色
                    painter.setBrush(pointColor[i - 30]); // 设置画刷颜色
                    painter.drawEllipse(adjustedPos, 5, 5); // 绘制半径为 5 的圆形点
                }
                i++;
            }
        }
    }

    // 绘制线段
    if (drawLines && !connectionSequence.isEmpty()) {
        for (int i = 0; i < currentLineIndex && i < connectionSequence.size() - 1; ++i) {
            int startIdx = connectionSequence[i]; // 起始点索引
            int endIdx = connectionSequence[i + 1]; // 结束点索引
            if (startIdx < adjustedPositionsList.size() && endIdx < adjustedPositionsList.size()) {
                QPointF startPos = adjustedPositionsList[startIdx]; // 起始点位置
                QPointF endPos = adjustedPositionsList[endIdx]; // 结束点位置

                // 创建渐变画笔
                QLinearGradient gradient(startPos, endPos); // 从起始点到结束点创建线性渐变
                gradient.setColorAt(0, QColor(17, 72, 180, 120)); // 渐变开始颜色（蓝色，不透明）
                gradient.setColorAt(1, QColor(17, 72, 180, 200));  // 渐变结束颜色（蓝色，半透明）

                QPen pen(gradient, 5); // 创建渐变画笔，设置宽度为 5
                painter.setPen(pen); // 设置画笔

                painter.drawLine(startPos, endPos); // 绘制线段
            }
        }
    }
}

// 更新线条动画
void TravelLabel::updateLineAnimation()
{
    if (currentLineIndex < connectionSequence.size() - 1) {
        currentLineIndex++; // 增加线段索引
        update(); // 触发重绘
    } else {
        currentLineIndex = 0; // 重新开始动画
        update(); // 触发重绘
        // lineAnimationTimer->stop(); // 动画结束（已注释掉，可能考虑停止动画）
    }
}

// 鼠标点击事件处理
void TravelLabel::mousePressEvent(QMouseEvent *event)
{
    if (event->button() == Qt::RightButton) {
        int x = event->x(); // 获取点击的 X 坐标
        int y = event->y(); // 获取点击的 Y 坐标
        emit coordinatesClicked(x, y);  // 发送点击坐标的信号
    }
    QLabel::mousePressEvent(event);  // 调用父类的鼠标事件处理
}

// 根据位置查找兴趣点
int TravelLabel::findInterestByLocation(int x, int y){
    bool matchFound = false; // 标志是否找到匹配点

    for (const QPointF &point : adjustedPositionsList) {
        // 如果点击位置接近任何点
        if (qAbs(point.x() - x) <= 5 && qAbs(point.y() - y) <= 5) {
            int index = adjustedPositionsList.indexOf(point); // 获取点的索引
            QString spotName = orderedNames.at(index); // 获取点的名称
            qDebug() << "点击的坐标: (" << x << "," << y << ")"; // 输出点击坐标
            qDebug() << "匹配的景点: " << spotName << ", 景点坐标: (" << point.x() << "," << point.y() << ")"; // 输出匹配点的信息

            return index; // 返回匹配点的索引
        }
    }
    if (!matchFound) {
        qDebug() << "点击的坐标: (" << x << "," << y << "), 请重新选择"; // 输出未找到匹配点的提示信息
        return -1; // 返回 -1 表示未找到匹配点
    }
}
